/************************************************************************
 * @file PluginContext.cpp
 * @author Ian Chen
 * @version 1.0
 *
 * @section LICENSE
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details at
 * http://www.gnu.org/licenses/lgpl.html
 *
 ************************************************************************/
#include <QDir>
#include <QCoreApplication>

#include <plugin/plugin/PluginContext.h>

namespace antu
{
namespace plugin
{
PluginContext::PluginContext()
{
    this->setApplicationPath(qApp->applicationDirPath());
}

PluginContext::PluginContext(const map<QString, QObject*>& context)
{
    this->setApplicationPath(qApp->applicationDirPath());
    this->m_oEnvironmentContext.insert(context.begin(), context.end());
}

PluginContext::PluginContext( const map<QString, QObject*>& context, const map<QString, QVariant>& settings )
{
    this->setApplicationPath(qApp->applicationDirPath());
    this->m_oEnvironmentContext.insert(context.begin(), context.end());
    this->m_oEnvironmentSettings.insert(settings.begin(), settings.end());
}

PluginContext::PluginContext(const map<QString, QVariant> &settings, const QString &path)
{
    this->setApplicationPath(path);
    this->m_oEnvironmentSettings.insert(settings.begin(), settings.end());
}

PluginContext::~PluginContext()
{
    map<QString, QObject*>::iterator iter = this->m_oEnvironmentContext.begin();
    map<QString, QObject*>::iterator end = this->m_oEnvironmentContext.end();

    for (; iter != end; iter++)
    {
        delete iter->second;
    }
    this->m_oEnvironmentContext.clear();
    this->m_oEnvironmentSettings.clear();
}

QString PluginContext::applicationPath() const
{
    return this->m_sApplicationPath;
}

QString PluginContext::installationPath() const
{
    return this->m_sDownloadPath;
}

QString PluginContext::pluginPath() const
{
    return this->m_sPluginPath;
}

void PluginContext::setApplicationPath(const QString& path)
{
    this->m_sApplicationPath = path;

    QDir appPath(path);
    this->m_sDownloadPath = appPath.absoluteFilePath("temp");
    this->m_sPluginPath = appPath.absoluteFilePath("conf");
    this->m_sLanguagePath = appPath.absoluteFilePath("lang");
}

QObject* PluginContext::operator [](const QString& name)
{
    map<QString, QObject*>::iterator iterator = this->m_oEnvironmentContext.find(name);

    if (iterator != this->m_oEnvironmentContext.end())
    {
        return iterator->second;
    }
    else
    {
        return nullptr;
    }
}

QString PluginContext::applicationGroup() const
{
    return this->m_sApplicationGroup;
}

void PluginContext::setApplicationGroup( const QString& group )
{
    this->m_sApplicationGroup = group;
}

QObject* PluginContext::contextObjectAt( const QString& name ) const
{
    map<QString, QObject*>::const_iterator iterator = this->m_oEnvironmentContext.find(name);

    if (iterator != this->m_oEnvironmentContext.end())
    {
        return iterator->second;
    }
    else
    {
        return nullptr;
    }
}

bool PluginContext::addContextObject(const QString &name, QObject *pContextObject)
{
    auto iter = this->m_oEnvironmentContext.find(name);
    if (iter == this->m_oEnvironmentContext.end())
    {
        this->m_oEnvironmentContext.insert(pair<QString, QObject*>(name, pContextObject));
        return true;
    }
    else
    {
        return false;
    }
}

QVariant PluginContext::settingAt( const QString& name ) const
{
    map<QString, QVariant>::const_iterator iter = this->m_oEnvironmentSettings.find(name);
    if (iter != this->m_oEnvironmentSettings.end())
    {
        return iter->second;
    }
    else
    {
        return QVariant();
    }
}

bool PluginContext::addContextSetting(const QString &name, const QVariant &value)
{
    auto iter = this->m_oEnvironmentSettings.find(name);
    if (iter == this->m_oEnvironmentSettings.end())
    {
        this->m_oEnvironmentSettings.insert(pair<QString, QVariant>(name, value));
        return true;
    }
    else
    {
        return false;
    }
}

QString PluginContext::languagePath()
{
    return this->m_sLanguagePath;
}

QString PluginContext::applicationName() const
{
    return this->m_sApplicationName;
}

void PluginContext::setApplicationName(const QString &name)
{
    this->m_sApplicationName = name;
}
}
}
